package jdom;
import java.util.ArrayList;
import java.util.Iterator;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;

public class XmlContentGetterUsingJdom {

	private final static Namespace NAMESPACE = Namespace
			.getNamespace("http://www.libraries.org");

	/**
	 * 
	 * @param doc
	 * @return
	 */
	public ArrayList<Library> getAllNewLibraries(Document doc,
			ArrayList<Library> alreadyStoredLibraries) {
		ArrayList<Library> result = new ArrayList<Library>();
		Iterator<?> i = doc.getRootElement().getChildren().iterator();
		while (i.hasNext()) {
			Element e = (Element) i.next();

			if (e.getName().equals(XmlTags.TAG_LIBRARIES)) {
				/*
				 * In [software/libraries] now
				 */
				for (Object lib : e.getChildren()) {
					/*
					 * In [software/libraries/library] now
					 */
					try {
						Element libEl = (Element) lib;

						Library library = createLibraryFromElement(libEl);

						if (!Utils.isAlreadyContained(library,
								alreadyStoredLibraries)) {
							result.add(library);
						}

					} catch (ClassCastException cc) {
						cc.printStackTrace();
						continue;
					}
				}
			}
		}
		return result;
	}

	/**
	 * 
	 * @param doc
	 * @param alreadyStoredDevelopers
	 *            list of developers that are already stored. Those that are
	 *            stored will not be returned again
	 * @return
	 */
	public ArrayList<Developer> getAllNewDevelopers(Document doc,
			ArrayList<Developer> alreadyStoredDevelopers) {
		ArrayList<Developer> result = new ArrayList<Developer>();
		Iterator<?> i = doc.getRootElement().getChildren().iterator();
		while (i.hasNext()) {
			Element e = (Element) i.next();

			if (e.getName().equals(XmlTags.TAG_DEVELOPERS)) {
				/*
				 * In [software/developers] now
				 */
				for (Object dev : e.getChildren()) {
					/*
					 * In [software/developers/developer] now
					 */
					try {
						Element devEl = (Element) dev;

						Developer developer = createDeveloperFromElement(devEl);

						if (!Utils.isAlreadyContained(developer,
								alreadyStoredDevelopers)) {
							result.add(developer);
						}

					} catch (ClassCastException cc) {
						cc.printStackTrace();
						continue;
					}
				}
			}
		}
		return result;
	}

	/**
	 * 
	 * @param libEl
	 * @param library
	 */
	private Library createLibraryFromElement(Element libEl) {

		Library resultLibrary = new Library(
				libEl.getAttributeValue(XmlTags.TAG_LIBRARY_ATTRIBUTE_LIBRARY_ID));

		resultLibrary.setName(libEl.getChildText(XmlTags.TAG_LIBRARY_TAG_NAME,
				NAMESPACE));
		resultLibrary.setVersion(libEl.getChildText(
				XmlTags.TAG_LIBRARY_TAG_VERSION, NAMESPACE));
		resultLibrary.setLanguage(libEl.getChildText(
				XmlTags.TAG_LIBRARY_TAG_LANGUAGE, NAMESPACE));
		resultLibrary.setSource(libEl.getChildText(
				XmlTags.TAG_LIBRARY_TAG_SOURCE, NAMESPACE));

		ArrayList<String> developers = new ArrayList<String>();
		for (Object libDev : libEl.getChildren(
				XmlTags.TAG_LIBRARY_TAG_DEVELOPER, NAMESPACE)) {
			try {
				Element libDevEl = (Element) libDev;
				String libDevRef = libDevEl
						.getAttributeValue(XmlTags.TAG_LIBRARY_TAG_DEVELOPER_ATTRIBUTE_REF);
				if (!developers.contains(libDevRef)) {
					developers.add(libDevRef);
				}
			} catch (ClassCastException e2) {
				e2.printStackTrace();
				continue;
			}
		}
		resultLibrary.setDevelopers(developers);

		ArrayList<String> dependencies = new ArrayList<String>();
		for (Object libDep : libEl.getChildren(
				XmlTags.TAG_LIBRARY_TAG_DEPENDENCY, NAMESPACE)) {
			try {
				Element libDepEl = (Element) libDep;
				String libDepRef = libDepEl
						.getAttributeValue(XmlTags.TAG_LIBRARY_TAG_DEPENDENCY_ATTRIBUTE_REF);
				if (!dependencies.contains(libDepRef)) {
					dependencies.add(libDepRef);
				}
			} catch (ClassCastException e2) {
				e2.printStackTrace();
				continue;
			}
		}
		resultLibrary.setDependencies(dependencies);

		return resultLibrary;
	}

	/**
	 * 
	 * @param devEl
	 * @return
	 */
	private Developer createDeveloperFromElement(Element devEl) {

		Developer resultDeveloper = new Developer(
				devEl.getAttributeValue(XmlTags.TAG_DEVELOPER_ATTRIBUTE_ID));

		resultDeveloper.setName(devEl.getChildText(
				XmlTags.TAG_DEVELOPER_TAG_NAME, NAMESPACE));
		resultDeveloper.setWebsite(devEl.getChildText(
				XmlTags.TAG_DEVELOPER_TAG_WEBSITE, NAMESPACE));

		return resultDeveloper;
	}
}
